home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Science / µSim 1.0b5 folder / source / Microprogram_Ed.c < prev    next >
Encoding:
Text File  |  1994-10-04  |  25.4 KB  |  972 lines  |  [TEXT/MMCC]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. //#pragma load "MacDump"
  11.  
  12. #include    "UtilsSys7.h"
  13. #include    "Globals.h"
  14. #include    "Animation.h"
  15. #include    "ControlStore.h"
  16. #include    "CursorBalloon.h"
  17. #include    "DoMenu.h"
  18. #include    "Main.h"
  19. #include    "Microprogram_Ed.h"
  20. #include    "SimAsm.h"
  21. #include    "Independents.h"
  22.  
  23. #if defined(FabSystem7orlater)
  24.  
  25.  
  26. enum {
  27. kLEN_MIR = 4
  28. };
  29.  
  30. /* Cursor keys */
  31. enum cursorkeys {
  32. kcursLeft = 0x1c,
  33. kcursRight,
  34. kcursUp,
  35. kcursDown
  36. };
  37.  
  38. enum microedstrs {
  39. kSTR_ALUINPUT = 1,
  40. kSTR_TO
  41. };
  42.  
  43. enum {
  44. kW_STRINGS = 259
  45. };
  46.  
  47. enum busrequests {
  48. kREQ_NO = 1,
  49. kREQ_READ,
  50. kREQ_WRITE
  51. };
  52.  
  53. TEHandle TEs[2];
  54. ListHandle    Lists[2];
  55.  
  56. RectPtr    keyrects[kN_RECTS];
  57. ControlHandle    controls[kNUM_CONTROLS];
  58. ControlHandle    RadioSelected;
  59. short    keyDownDest;
  60. short    theSelection[2] = { 0, 0 };
  61. short    maxLLine[2];
  62.  
  63. static Rect    selectRect;
  64. static union u_mir editmir;
  65. Boolean    arrowDrawn = false;
  66. Boolean    draggedOnComments = false;
  67.  
  68. void ChangeAnim_mar(short);
  69. void ChangeAnim_mbr(short);
  70. void ChangeAnim_map(short);
  71. void ChangeAnim_amux(short);
  72. void ChangeAnim_alu(short new, short old);
  73. void ChangeAnim_cond(short new, short old);
  74. void ChangeAnim_sh(short new, short old);
  75. void ChangeAnim_busreq(short new, short old);
  76. void ChangeAnim_cbus(Boolean new, Boolean old);
  77.  
  78. /* ===============static prototypes=============== */
  79. static void SettheInputTo(TEHandle thisHandle);
  80. static void Frame(void);
  81. static void UnFrame(void);
  82. static void DoChar(short which, unsigned char theChar);
  83. static short StartsWith(short which, unsigned char c);
  84. static void HandleClick(TEHandle theTE, short obj);
  85. static void ChangedComment(void);
  86. static void ChangedBranchTo(void);
  87. static void ResetMirAndComment(void);
  88. static void GotDragOnComments(void);
  89.  
  90. /* =============================================== */
  91.  
  92. #pragma segment __%Main
  93.  
  94. /* myCallback: when finished playing, we post an event so that the main loop
  95. is not forced to continuously test a global variable */
  96.  
  97. pascal void myCallback(SndChannelPtr theChan, const SndCommand *)
  98. {
  99. (void)PostEvent(app3Evt, (long)theChan);
  100. }
  101.  
  102. #pragma segment Microprog
  103.  
  104. /* EraseArrowRect: erases the rectangle containing the arrow */
  105.  
  106. void EraseArrowRect(void)
  107. {
  108. Rect    tempRect;
  109.  
  110. tempRect.right = keyrects[kKEY_LIST]->left - klateralCellTweek + 1;
  111. tempRect.top = PRCT_T(gWPtr_Microprogram_Ed);
  112. tempRect.left = tempRect.right - karrowDistFromList - 1;
  113. tempRect.bottom = PRCT_B(gWPtr_Microprogram_Ed);
  114. EraseRect(&tempRect);
  115. arrowDrawn = false;
  116. }
  117.  
  118. /* RefreshTE: refreshes a textedit field in the window */
  119.  
  120. void RefreshTE(short whichTE)
  121. {
  122. Rect    tempRect = *keyrects[whichTE];
  123. GrafPtr    savePort;
  124.  
  125. GetPort(&savePort);
  126. SetPort(gWPtr_Microprogram_Ed);
  127. InsetRect(&tempRect, 1, 1);
  128. EraseRect(&tempRect);
  129. TEUpdate(keyrects[whichTE], TEs[whichTE]);
  130. SetPort(savePort);
  131. }
  132.  
  133. /* SetControlsFromMir: sets up the controls to reflect the
  134. micro instruction register */
  135.  
  136. void SetControlsFromMir(union u_mir oldmir)
  137. {
  138. Str255 tempS;
  139. GrafPtr    savePort;
  140.  
  141. lastCommand = kST_STOPPED;
  142. GetPort(&savePort);
  143. SetPort(gWPtr_Microprogram_Ed);
  144. SetCtlValue(controls[kPOPUP_ABUS], editmir.bits.a + 1);
  145. SetCtlValue(controls[kPOPUP_BBUS], editmir.bits.b + 1);
  146. if (editmir.bits.c != oldmir.bits.c) {
  147.     SetCtlValue(controls[kPOPUP_CBUS], (editmir.bits.dsc ? 0 : editmir.bits.c + 2));
  148.     ChangeAnim_cbus(editmir.bits.dsc, oldmir.bits.dsc);
  149.     }
  150. if (editmir.bits.mar != oldmir.bits.mar) {
  151.     SetCtlValue(controls[kCHECK_MAR], editmir.bits.mar);
  152.     ChangeAnim_mar(editmir.bits.mar);
  153.     }
  154. if (editmir.bits.mbr != oldmir.bits.mbr) {
  155.     SetCtlValue(controls[kCHECK_MBR], editmir.bits.mbr);
  156.     ChangeAnim_mbr(editmir.bits.mbr);
  157.     }
  158. if ((1 + editmir.bits.rd + (editmir.bits.wr << 1)) !=
  159.     (1 + oldmir.bits.rd + (oldmir.bits.wr << 1))) {
  160.     SetCtlValue(controls[kPOPUP_BUSREQ], 1 + editmir.bits.rd + (editmir.bits.wr << 1));
  161.     ChangeAnim_busreq(1 + editmir.bits.rd + (editmir.bits.wr << 1),
  162.                         1 + oldmir.bits.rd + (oldmir.bits.wr << 1));
  163.     }
  164. if (editmir.bits.shift != oldmir.bits.shift) {
  165.     SetCtlValue(controls[kPOPUP_SHIFTER], editmir.bits.shift + 1);
  166.     ChangeAnim_sh(editmir.bits.shift, oldmir.bits.shift);
  167.     }
  168. if (editmir.bits.cond != oldmir.bits.cond) {
  169.     SetCtlValue(controls[kPOPUP_BRANCH], editmir.bits.cond + 1);
  170.     ChangeAnim_cond(editmir.bits.cond, oldmir.bits.cond);
  171.     }
  172. if (editmir.bits.alu != oldmir.bits.alu) {
  173.     SetCtlValue(controls[kPOPUP_ALU], editmir.bits.alu + 1);
  174.     ChangeAnim_alu(editmir.bits.alu, oldmir.bits.alu);
  175.     }
  176. if (editmir.bits.amux != oldmir.bits.amux) {
  177.     SetCtlValue(controls[kRADIO_ABUS], 1 - editmir.bits.amux);
  178.     SetCtlValue(controls[kRADIO_MBR], editmir.bits.amux);
  179.     RadioSelected = controls[kRADIO_ABUS + editmir.bits.amux];
  180.     ChangeAnim_amux(editmir.bits.amux);
  181.     }
  182. if (editmir.bits.map != oldmir.bits.map) {
  183.     SetCtlValue(controls[kCHECK_ACTMAP], editmir.bits.map);
  184.     ChangeAnim_map(editmir.bits.map);
  185.     }
  186. //if (editmir.bits.addr != oldmir.bits.addr) {
  187.     MyNumToString(editmir.bits.addr, tempS);
  188.     TESetText(&tempS[1], Length(tempS), TEs[kKEY_BRTO]);
  189.     RefreshTE(kKEY_BRTO);
  190. //    }
  191. SetPort(savePort);
  192. }
  193.  
  194. /* da schiaffare dentro la routine successiva */
  195. const short martoActDeact[] = { kC_MAR1, kC_MAR2, kC_MAR3, kC_MAR4, 0 };
  196. const short marifnotSubc[] = { kP_MAR, kP_BLTCH2MAR1, kP_BLTCH2MAR2, 0 };
  197.  
  198. void ChangeAnim_mar(short curVal)
  199. {
  200. if (curVal) {
  201.     ActivateObjs(martoActDeact);
  202.     if (gRstatus < kST_STEPSUBCYC)
  203.         ActivateObjs(marifnotSubc);
  204.     }
  205. else {
  206.     DeactivateObjs(martoActDeact);
  207.     if (gRstatus < kST_STEPSUBCYC)
  208.         DeactivateObjs(marifnotSubc);
  209.     }
  210. }
  211.  
  212. /* da schiaffare dentro la routine successiva */
  213. const short mbrtoActDeact[] = { kC_MBR1, kC_MBR2, kC_MBR3, 0 };
  214. const short mbrifnotSubc[] = { kP_MBR, kP_SH2MBR1, kP_SH2MBR2, 0 };
  215.  
  216. void ChangeAnim_mbr(short curVal)
  217. {
  218. if (curVal) {
  219.     ActivateObjs(mbrtoActDeact);
  220.     if (gRstatus < kST_STEPSUBCYC)
  221.         ActivateObjs(mbrifnotSubc);
  222.     }
  223. else {
  224.     DeactivateObjs(mbrtoActDeact);
  225.     if (gRstatus < kST_STEPSUBCYC)
  226.         DeactivateObjs(mbrifnotSubc);
  227.     }
  228. }
  229.  
  230. /* da schiaffare dentro la routine successiva */
  231. const short maptoActDeact[] = { kP_MAP, kP_MAPREGS, 0 };
  232.  
  233. void ChangeAnim_map(short curVal)
  234. {
  235. if (gRstatus < kST_STEPSUBCYC)
  236.     if (curVal)
  237.         ActivateObjs(maptoActDeact);
  238.     else
  239.         DeactivateObjs(maptoActDeact);
  240. }
  241.  
  242. /* da schiaffare dentro la routine successiva */
  243. const short amuxtoActDeact[] = { kC_AMUX1, kC_AMUX2, kC_AMUX3, 0 };
  244. const short amuxifnotSubc[] = { kP_AMUX, kP_MBR2AMUX, 0 };    
  245. const short amuxtoDeact[] = { kP_ALTCH2AMUX, 0 };
  246. const short amux2ifnotSubc[] = { kP_MBR2AMUX, 0 };
  247. const short amuxtoAct[] = { kP_ALTCH2AMUX, kP_AMUX, 0 };
  248.  
  249. void ChangeAnim_amux(short curVal)
  250. {
  251. if (curVal) {
  252.     ActivateObjs(amuxtoActDeact);
  253.     if (gRstatus < kST_STEPSUBCYC) {
  254.         DeactivateObjs(amuxtoDeact);
  255.         ActivateObjs(amuxifnotSubc);
  256.         }
  257.     }
  258. else {
  259.     DeactivateObjs(amuxtoActDeact);
  260.     if (gRstatus < kST_STEPSUBCYC) {
  261.         ActivateObjs(amuxtoAct);
  262.         DeactivateObjs(amux2ifnotSubc);
  263.         }
  264.     }
  265. }
  266.  
  267. /* da schiaffare dentro la routine successiva */
  268. const short alutoActDeact[] = { kC_ALU1, kC_ALU2, 0 };
  269. const short aluifnotSubc[] = { kP_ALU, 0 };
  270.  
  271. void ChangeAnim_alu(short curVal, short oldVal)
  272. {
  273. if (curVal) {
  274.     if (oldVal == 0) {
  275.         ActivateObjs(alutoActDeact);
  276.         if (gRstatus < kST_STEPSUBCYC)
  277.             ActivateObjs(aluifnotSubc);
  278.         }
  279.     }
  280. else {
  281.     DeactivateObjs(alutoActDeact);
  282.     if (gRstatus < kST_STEPSUBCYC)
  283.         DeactivateObjs(aluifnotSubc);
  284.     }
  285. }
  286.  
  287. /* da schiaffare dentro la routine successiva */
  288. const short condtoActDeact[] = { kP_MSL, kC_COND1, kC_COND2, kC_MSL2MMUX1, kC_MSL2MMUX2, 0 };
  289.  
  290. void ChangeAnim_cond(short curVal, short oldVal)
  291. {
  292. if (curVal) {
  293.     if (oldVal == 0)
  294.         ActivateObjs(condtoActDeact);
  295.     }
  296. else
  297.     DeactivateObjs(condtoActDeact);
  298. }
  299.  
  300. /* da schiaffare dentro la routine successiva */
  301. const short shtoActDeact[] = { kC_SHFT1, kC_SHFT2, 0 };
  302. const short shifnotSubc[] = { kP_SHIFTER, 0 };
  303.  
  304. void ChangeAnim_sh(short curVal, short oldVal)
  305. {
  306. if (curVal) {
  307.     if (oldVal == 0) {
  308.         ActivateObjs(shtoActDeact);
  309.         if (gRstatus < kST_STEPSUBCYC)
  310.             ActivateObjs(shifnotSubc);
  311.         }
  312.     }
  313. else {
  314.     DeactivateObjs(shtoActDeact);
  315.     if (gRstatus < kST_STEPSUBCYC)
  316.         DeactivateObjs(shifnotSubc);
  317.     }
  318. }
  319.  
  320. /* da schiaffare dentro la routine successiva */
  321. const short busreqNOtoActDeact[] = { kP_MAR2MEM, kP_MBRMEM, 0 };
  322. const short busreqREADtoActDeact[] = { kC_READ1, kC_READ2, kC_READ3, 0 };
  323. const short busreqWRITEtoActDeact[] = { kC_WRITE1, kC_WRITE2, kC_WRITE3, 0 };
  324.  
  325. void ChangeAnim_busreq(short curVal, short oldVal)
  326. {
  327. switch(oldVal) {
  328.     case kREQ_NO:
  329.         if (gRstatus < kST_STEPSUBCYC)
  330.             ActivateObjs(busreqNOtoActDeact);
  331.         break;
  332.     case kREQ_READ:
  333.         DeactivateObjs(busreqREADtoActDeact);
  334.         break;
  335.     case kREQ_WRITE:
  336.         DeactivateObjs(busreqWRITEtoActDeact);
  337.     }
  338. switch(curVal) {
  339.     case kREQ_NO:
  340.         if (gRstatus < kST_STEPSUBCYC)
  341.             DeactivateObjs(busreqNOtoActDeact);
  342.         break;
  343.     case kREQ_READ:
  344.         ActivateObjs(busreqREADtoActDeact);
  345.         break;
  346.     case kREQ_WRITE:
  347.         ActivateObjs(busreqWRITEtoActDeact);
  348.     }
  349. }
  350.  
  351. /* da schiaffare dentro la routine successiva */
  352. const short cbustoActDeact3[] = { kP_SH2REGS1, kP_SH2REGS2, kP_SH2REGS3, 0 };
  353. const short cbustoActDeact1[] = { kC_DSC, 0 };
  354.  
  355. void ChangeAnim_cbus(Boolean curVal, Boolean oldVal)
  356. {
  357. if (curVal) {
  358.     if (oldVal == false) {
  359.         if (gRstatus < kST_STEPSUBCYC)
  360.             DeactivateObjs(cbustoActDeact3);
  361.         ActivateObjs(cbustoActDeact1);
  362.         }
  363.     }
  364. else if (oldVal) {
  365.     if (gRstatus < kST_STEPSUBCYC)
  366.         ActivateObjs(cbustoActDeact3);
  367.     DeactivateObjs(cbustoActDeact1);
  368.     }
  369. }
  370.  
  371. /* SettheInputTo: the input TextEdit field has changed */
  372.  
  373. static void SettheInputTo(TEHandle thisHandle)
  374. {
  375. if (gTheInput)
  376.     TEDeactivate(gTheInput);
  377. if (gTheInput = thisHandle)
  378.     TEActivate(gTheInput);
  379. }
  380.  
  381. /* Frame: puts up the standard bordering for active lists */
  382.  
  383. static void Frame(void)
  384. {
  385. PenState    curPen;
  386.  
  387. selectRect = *keyrects[keyDownDest];
  388. InsetRect(&selectRect, -4, -4);
  389. GetPenState(&curPen);
  390. PenMode(patCopy);
  391. PenSize(2, 2);
  392. FrameRect(&selectRect);
  393. SetPenState(&curPen);
  394. }
  395.  
  396. /* UnFrame: removes the standard bordering for active lists */
  397.  
  398. static void UnFrame(void)
  399. {
  400. PenState    curPen;
  401.  
  402. GetPenState(&curPen);
  403. PenMode(patXor);
  404. PenSize(2, 2);
  405. FrameRect(&selectRect);
  406. SetPenState(&curPen);
  407. }
  408.  
  409. /* HandleClick: the user has clicked in a list or editable text */
  410.  
  411. static void HandleClick(TEHandle theTE, short obj)
  412. {
  413. if (keyDownDest != obj) {
  414.     if (keyDownDest >= kKEY_LIST)
  415.         UnFrame();
  416.     SettheInputTo(theTE);
  417.     if ((keyDownDest = obj) >= kKEY_LIST)
  418.         Frame();
  419.     }
  420. }
  421.  
  422. void Update_Microprogram_Ed(WindowPtr w)
  423. {
  424. PenState    curPen;
  425. Rect    tempRect;
  426. register Handle    tempH;
  427.  
  428. TextFont(systemFont);
  429. TextSize(12);
  430. HLock(tempH = Get1Resource('STR#', kW_STRINGS));
  431. MoveTo(keyrects[kKEY_STRINGS]->left, keyrects[kKEY_STRINGS]->top);
  432. DrawString((ConstStr255Param)GetPtrIndHString(tempH, kSTR_ALUINPUT - 1));
  433. MoveTo(keyrects[kKEY_STRINGS]->right, keyrects[kKEY_STRINGS]->bottom);
  434. DrawString((ConstStr255Param)GetPtrIndHString(tempH, kSTR_TO - 1));
  435. HUnlock(tempH);
  436. FrameRect(keyrects[kKEY_COMMENT]);
  437. FrameRect(keyrects[kKEY_BRTO]);
  438. tempRect = *keyrects[kKEY_LIST];
  439. tempRect.right -= kScrollbarAdjust;
  440. InsetRect(&tempRect, -1, -1);
  441. FrameRect(&tempRect);
  442. tempRect = *keyrects[kKEY_INSTR];
  443. tempRect.right -= kScrollbarAdjust;
  444. InsetRect(&tempRect, -1, -1);
  445. FrameRect(&tempRect);
  446. if (gInTheForeground &&(keyDownDest >= kKEY_LIST)&&(w == FrontWindow())) {
  447.     GetPenState(&curPen);
  448.     PenSize(2, 2);
  449.     FrameRect(&selectRect);
  450.     SetPenState(&curPen);
  451.     }
  452. TextFont(geneva);
  453. TextSize(9);
  454. LUpdate(w->visRgn, Lists[kL_INSTR]);
  455. LUpdate(w->visRgn, Lists[kL_COMMENTS]);
  456. RefreshTE(kKEY_BRTO);
  457. RefreshTE(kKEY_COMMENT);
  458. UpdtControl(w, w->visRgn);
  459. }
  460.  
  461. /* PrepareOpenMicroprogram: we hilite some objects before
  462. showing up the window */
  463.  
  464. /* da schiaffare dentro la routine successiva */
  465. const short toBeMoreClear[] = { kP_AMUX2ALU, kP_ALU2SH, kP_REG2LTCH1, kP_REG2LTCH2,
  466.                     kP_BLTCH2ALU, kP_CST2MIR, kC_ABC1, kC_ABC2, kC_ABC3, kC_ABC4, 0 };
  467.  
  468. void PrepareOpenMicroprogram(void)
  469. {
  470. if (((WindowPeek)gWPtr_Microprogram_Ed)->visible == false)
  471.     ActivateObjs(toBeMoreClear);
  472. }
  473.  
  474. void Activate_Microprogram_Ed(WindowPtr , Boolean Do_An_Activate)
  475. {
  476.  
  477. LActivate(Do_An_Activate, Lists[kL_COMMENTS]);
  478. LActivate(Do_An_Activate, Lists[kL_INSTR]);
  479. if (Do_An_Activate == true) {
  480.     if (keyDownDest < kKEY_LIST)
  481.         SettheInputTo(TEs[keyDownDest]);
  482.     else
  483.         Frame();
  484.     }
  485. else {
  486.     if (keyDownDest >= kKEY_LIST)
  487.         UnFrame();
  488.     else
  489.         SettheInputTo(nil);
  490.     }
  491. }
  492.  
  493. /* Microprog_TextWasModified: tells us that a text field has been modified */
  494.  
  495. void Microprog_TextWasModified(void)
  496. {
  497. if (gTheInput == TEs[kKEY_COMMENT])
  498.     ChangedComment();
  499. else if (gTheInput == TEs[kKEY_BRTO])
  500.     ChangedBranchTo();
  501. DocumentIsDirty(true);
  502. }
  503.  
  504. /* ChangedComment: the comment field has changed */
  505.  
  506. static void ChangedComment(void)
  507. {
  508. register Handle    typedText;
  509. register Point    tempCell;
  510. register SignedByte    savedState;
  511.  
  512. tempCell.h = 0;
  513. tempCell.v = theSelection[kL_COMMENTS];
  514. savedState = WantThisHandleSafe(typedText = (Handle)TEGetText(TEs[kKEY_COMMENT]));
  515. LSetCell(*typedText, InlineGetHandleSize(typedText), tempCell, Lists[kL_COMMENTS]);
  516. HSetState(typedText, savedState);
  517. }
  518.  
  519. /* ChangedBranchTo: the branch to… field has changed */
  520.  
  521. static void ChangedBranchTo(void)
  522. {
  523. Str255    tempS;
  524. Size    tSize = 0L;
  525. register union u_mir    tempMir;
  526.  
  527. GetIText(TEGetText(TEs[kKEY_BRTO]), tempS);
  528. if (tempS[0] != 0)
  529.     StringToNum(tempS, &tSize);
  530. /* …stuff it into the micro instruction */
  531. tempMir = editmir;
  532. tempMir.bits.addr = tSize;
  533. SetMir(tempMir.cstore);
  534. }
  535.  
  536. /* ChangedListSelection: the selection in a list has changed */
  537.  
  538. void ChangedListSelection(Point newCell, short which, Boolean inCkLoop)
  539. {
  540. Str255    tempS;
  541. GrafPtr    savePort;
  542. register ROpcodePtr    myOpcodePtr;
  543. Point instr;
  544. short    length;
  545.  
  546. GetPort(&savePort);
  547. SetPort(gWPtr_Microprogram_Ed);
  548. if (which == kL_COMMENTS) {
  549.     if (inCkLoop) {
  550. /* we must update the associative memory… */
  551.         *(long *)&instr = 0L;
  552.         if (LGetSelect(true, &instr, Lists[kL_INSTR])) {
  553.             register Byte i;
  554.  
  555.             myOpcodePtr = ((ROpcodePtr)(((short *)*Get1Resource(krInstructions, kOPCODES)) + 1))
  556.                             + instr.v;
  557.             for (i = myOpcodePtr->offsetHB; i <= myOpcodePtr->lastHB; i++)
  558.                 *(gAssMemory + i) = newCell.v;
  559.             }
  560.         }
  561. /* …and update the control store memory */
  562. /*    *(csMemory + theSelection[kL_COMMENTS]) = editmir;*/
  563. /* get cell contents and put into TextEdit field */
  564.     length = 255;    /* maximum length of text */
  565.     LGetCell(&tempS, &length, newCell, Lists[kL_COMMENTS]);
  566.     TESetText(&tempS, length, TEs[kKEY_COMMENT]);
  567.     RefreshTE(kKEY_COMMENT);
  568.     theSelection[which] = newCell.v;
  569. /* load the micro instruction we must edit from control store memory */
  570.     SetMir((*(gCsMemory + newCell.v)).cstore);
  571.     }
  572. else {    /* instruction list */
  573.     myOpcodePtr = ((ROpcodePtr)(((short *)*Get1Resource(krInstructions, kOPCODES))+1))
  574.                     + newCell.v;
  575.     if (*(gAssMemory + myOpcodePtr->offsetHB) != theSelection[kL_COMMENTS])
  576. /* the selected instruction is associated to a "comment" not selected */
  577.         SelectLLine(kL_COMMENTS, *(gAssMemory + myOpcodePtr->offsetHB));
  578.     }
  579. theSelection[which] = newCell.v;
  580. SetPort(savePort);
  581. }
  582.  
  583. void Do_Microprogram_Ed(WindowPtr w, EventRecord *theEvent)
  584. {
  585. Rect    tempRect;
  586. union u_mir    oldmir;
  587. Point    myPt;
  588. ControlHandle    theControl;
  589. register Boolean    DoubleClick, selectionFound;
  590.  
  591. myPt = theEvent->where;
  592. GlobalToLocal(&myPt);
  593. /* click in comment TE */
  594. if (PtInRect(myPt, keyrects[kKEY_COMMENT])) {
  595.     HandleClick(TEs[kKEY_COMMENT], kKEY_COMMENT);
  596.     TEClick(myPt, (theEvent->modifiers & shiftKey) != 0, TEs[kKEY_COMMENT]);
  597.     }
  598. /* click in branch to line TE */
  599. else if (PtInRect(myPt, keyrects[kKEY_BRTO])) {
  600.     HandleClick(TEs[kKEY_BRTO], kKEY_BRTO);
  601.     TEClick(myPt, (theEvent->modifiers & shiftKey) != 0, TEs[kKEY_BRTO]);
  602.     }
  603. else {
  604.     tempRect = *keyrects[kKEY_LIST];
  605.     InsetRect(&tempRect, -1, -1);
  606. /* click in comment list */
  607.     if (PtInRect(myPt, &tempRect)) {
  608.         HandleClick(nil, kKEY_LIST);
  609.         if (theEvent->modifiers & cmdKey)
  610.             SetCursor(*GetCursor(plusCursor));
  611.         DoubleClick = LClick(myPt, theEvent->modifiers, Lists[kL_COMMENTS]);
  612.         EraseArrowRect();
  613.         *(long *)(&myPt) = 0L;
  614.         selectionFound = LGetSelect(true, &myPt, Lists[kL_COMMENTS]);
  615.         if (theEvent->modifiers & cmdKey) {
  616.             oldmir = editmir;
  617.             oldmir.bits.addr = myPt.v;
  618.             SetMir(oldmir.cstore);
  619.             DocumentIsDirty(true);
  620.             InitCursor();
  621.             }
  622.         if (DoubleClick) {
  623.             if (editmir.bits.cond)
  624.                 SelectLLine(kL_COMMENTS, editmir.bits.addr);
  625.             }
  626.         else {
  627.             if (selectionFound) {
  628.                 if (myPt.v != theSelection[kL_COMMENTS])
  629.                     /* new item has been selected */
  630.                     ChangedListSelection(myPt, kL_COMMENTS, false);
  631.                 }
  632.             }
  633.         }
  634.     else {
  635.         tempRect = *keyrects[kKEY_INSTR];
  636.         InsetRect(&tempRect, -1, -1);
  637. /* click in instruction list */
  638.         if (PtInRect(myPt, &tempRect)) {
  639.             HandleClick(nil, kKEY_INSTR);
  640.             (void)LClick(myPt, theEvent->modifiers, Lists[kL_INSTR]);
  641.             if (draggedOnComments) {
  642.                 GotDragOnComments();
  643.                 }
  644.             tempRect = *keyrects[kKEY_INSTR];
  645.             tempRect.right -= kScrollbarAdjust;
  646.             if (PtInRect(myPt, &tempRect)) {
  647.                 *(long *)(&myPt) = 0L;
  648.                 if (LGetSelect(true, &myPt, Lists[kL_INSTR]))
  649.                     /* new item has been selected */
  650.                     ChangedListSelection(myPt, kL_INSTR, draggedOnComments);
  651.                 }
  652.             draggedOnComments = false;
  653.             ForceMouseMovedEvent();
  654.             }
  655.         else {
  656. /* click in controls */
  657.             if (FindControl(myPt, w, &theControl)) {
  658.                 oldmir = editmir;
  659.                 switch(TrackControl(theControl, myPt, (ControlActionUPP)-1L)) {
  660.                     register short newval;
  661.         
  662.                     case inLabel:
  663.                         if (theControl == controls[kPOPUP_ABUS])
  664.                             editmir.bits.a = GetCtlValue(theControl) - 1;
  665.                         else if (theControl == controls[kPOPUP_BBUS])
  666.                             editmir.bits.b = GetCtlValue(theControl) - 1;
  667.                         else if (theControl == controls[kPOPUP_CBUS]) {
  668.                             if (editmir.bits.c != (newval = (GetCtlValue(theControl)-2))) {
  669.                                 ChangeAnim_cbus(newval < 0, editmir.bits.dsc);
  670.                                 editmir.bits.c = newval;
  671.                                 editmir.bits.dsc = newval < 0;
  672.                                 }
  673.                             }
  674.                         else if (theControl == controls[kPOPUP_BUSREQ]) {
  675.                             register short newvalrd, newvalwr;
  676.         
  677.                             newvalrd = ((newval = GetCtlValue(theControl)) == kREQ_READ);
  678.                             newvalwr = (newval == kREQ_WRITE);
  679.                             if ((editmir.bits.rd != newvalrd)||(editmir.bits.wr != newvalwr)) {
  680.                                 ChangeAnim_busreq(newval, 1 + editmir.bits.rd + (editmir.bits.wr << 1));
  681.                                 editmir.bits.rd = newvalrd;
  682.                                 editmir.bits.wr = newvalwr;
  683.                                 }
  684.                             }
  685.                         else if (theControl == controls[kPOPUP_SHIFTER]) {
  686.                             if (editmir.bits.shift != (newval = (GetCtlValue(theControl)-1))) {
  687.                                 ChangeAnim_sh(newval, editmir.bits.shift);
  688.                                 editmir.bits.shift = newval;
  689.                                 }
  690.                             }
  691.                         else if (theControl == controls[kPOPUP_BRANCH]) {
  692.                             if (editmir.bits.cond != (newval = (GetCtlValue(theControl)-1))) {
  693.                                 ChangeAnim_cond(newval, editmir.bits.cond);
  694.                                 editmir.bits.cond = newval;
  695.                                 }
  696.                             }
  697.                         else if (theControl == controls[kPOPUP_ALU]) {
  698.                             if (editmir.bits.alu != (newval = (GetCtlValue(theControl)-1))) {
  699.                                 ChangeAnim_alu(newval, editmir.bits.alu);
  700.                                 editmir.bits.alu = newval;
  701.                                 }
  702.                             }
  703.                         break;
  704.                     case inCheckBox:
  705.                         if ((theControl == controls[kRADIO_ABUS])||(theControl == controls[kRADIO_MBR])) {
  706.                             if (RadioSelected != theControl) {
  707.                                 SetCtlValue(RadioSelected, 0);
  708.                                 SetCtlValue(theControl, 1);
  709.                                 RadioSelected = theControl;
  710.                                 ChangeAnim_amux(editmir.bits.amux = GetCtlValue(controls[kRADIO_MBR]));
  711.                                 }
  712.                             }
  713.                         else {    
  714.                             SetCtlValue(theControl, newval = (1 - GetCtlValue(theControl)));
  715.                             if (theControl == controls[kCHECK_MAR]) {
  716.                                 editmir.bits.mar = newval;
  717.                                 ChangeAnim_mar(newval);
  718.                                 }
  719.                             else if (theControl == controls[kCHECK_MBR]) {
  720.                                 editmir.bits.mbr = newval;
  721.                                 ChangeAnim_mbr(newval);
  722.                                 }
  723.                             else if (theControl == controls[kCHECK_ACTMAP]) {
  724.                                 editmir.bits.map = newval;
  725.                                 ChangeAnim_map(newval);
  726.                                 }
  727.                             }
  728.                     }
  729.                 if (editmir.cstore != oldmir.cstore) {
  730.                     UpdateMir(editmir);
  731.                     /* …and update the control store memory */
  732.                     *(gCsMemory + theSelection[kL_COMMENTS]) = editmir;
  733.                     DocumentIsDirty(true);
  734.                     }
  735.                 }
  736.             }
  737.         }
  738.     }
  739. }
  740.  
  741. void Key_Microprogram_Ed(EventRecord *theEvent, Boolean ignoreChar)
  742. {
  743. enum {
  744. kTabKey = 9
  745. };
  746.  
  747. GrafPtr    savePort;
  748. register unsigned char    ch;
  749.  
  750. GetPort(&savePort);
  751. SetPort(gWPtr_Microprogram_Ed);
  752. if ((ch = CHARFROMMESSAGE(theEvent->message)) == kTabKey) {
  753.     if (keyDownDest >= kKEY_LIST)
  754.         UnFrame();
  755.     keyDownDest = (theEvent->modifiers & shiftKey ?
  756.                     (keyDownDest == kKEY_INSTR ? kKEY_BRTO : keyDownDest + 1) :
  757.                     (keyDownDest == kKEY_BRTO ? kKEY_INSTR : keyDownDest - 1));
  758.     if (keyDownDest < kKEY_LIST) {
  759.         SettheInputTo(TEs[keyDownDest]);
  760.         TESetSelect(0, 32767, gTheInput);
  761.         }
  762.     else {
  763.         SettheInputTo(nil);
  764.         Frame();
  765.         }
  766.     }
  767. else if (gTheInput) {
  768.     if (ignoreChar == false)
  769.         TEKey(ch, gTheInput);
  770.     if ((ch < kcursLeft)||(ch > kcursDown))
  771.         Microprog_TextWasModified();
  772.     }
  773. else if (keyDownDest >= kKEY_LIST)
  774.     DoChar(keyDownDest - 2, ch);
  775. SetPort(savePort);
  776. }
  777.  
  778. static void DoChar(short item, unsigned char theChar)
  779. {
  780. register short    newSelect;
  781.  
  782. /* Take the char, and find the first line that starts with this char. */
  783. if ((newSelect = StartsWith(item, theChar)) != theSelection[item])
  784.     /* We've moved. Unhighlight the old. */
  785.     SelectLLine(item, newSelect);
  786. }
  787.  
  788. static short StartsWith(short elem, unsigned char c)
  789. {
  790. /* Check for cursor up, down. */
  791. if (c == kcursDown) {
  792.     /* Go up one, clamp at the end. */
  793.     return ((theSelection[elem] == maxLLine[elem]) ? theSelection[elem] :
  794.                 theSelection[elem] + 1);
  795.     }
  796. if (c == kcursUp) {
  797.     /* Go down one, clamp at the bottom. */
  798.     return((theSelection[elem] == 0) ? 0 : theSelection[elem] - 1);
  799.     }
  800. return (maxLLine[elem]);
  801. }
  802.  
  803. /* ResetMirAndComment: reset the micro instruction register and comment field */
  804.  
  805. static void ResetMirAndComment(void)
  806. {
  807. short    null = 0;
  808.  
  809. TESetText(&null, 0, TEs[kKEY_COMMENT]);
  810. RefreshTE(kKEY_COMMENT);
  811. ChangedComment();
  812. SetMir(0L);
  813. DocumentIsDirty(true);
  814. }
  815.  
  816. /* SendClipMsg: handle a clipboard request from the user */
  817.  
  818. OSErr SendClipMsg(short msg)
  819. {
  820. unsigned long    dataOffset;
  821. register long    length;
  822. register Handle    typedText;
  823. register SignedByte    savedState;
  824.  
  825. switch (msg) {
  826.     case kCLIPMSG_CUT:
  827.         if ((length = ZeroScrap()) == noErr)
  828.             if ((length = PutScrap(kLEN_MIR, kFCR_MINE, (Ptr)&editmir)) == noErr) {
  829.                 savedState = WantThisHandleSafe(typedText = (Handle)TEGetText(TEs[kKEY_COMMENT]));
  830.                 length = PutScrap(InlineGetHandleSize(typedText), 'TEXT', *typedText);
  831.                 HSetState(typedText, savedState);
  832.                 if (length == noErr) {
  833.                     (void)TEFromScrap();
  834.                     ResetMirAndComment();
  835.                     }
  836.                 }
  837.         break;
  838.     case kCLIPMSG_COPY:
  839.         if ((length = ZeroScrap()) == noErr)
  840.             if ((length = PutScrap(kLEN_MIR, kFCR_MINE, (Ptr)&editmir)) == noErr) {
  841.                 savedState = WantThisHandleSafe(typedText = (Handle)TEGetText(TEs[kKEY_COMMENT]));
  842.                 length = PutScrap(InlineGetHandleSize(typedText), 'TEXT', *typedText);
  843.                 HSetState(typedText, savedState);
  844.                 (void)TEFromScrap();
  845.                 }
  846.         break;
  847.     case kCLIPMSG_PASTE:
  848.         typedText = NewHandle(0);
  849.         if ((length = GetScrap(typedText, kFCR_MINE, (long *)&dataOffset)) == kLEN_MIR) {
  850.             SetMir(*(unsigned long *)*typedText);
  851.             DocumentIsDirty(true);
  852.             if ((length = GetScrap(typedText, 'TEXT', (long *)&dataOffset)) >= 0L) {
  853.                 savedState = WantThisHandleSafe(typedText);
  854.                 TESetText(*typedText, length, TEs[kKEY_COMMENT]);
  855.                 HSetState(typedText, savedState);
  856.                 RefreshTE(kKEY_COMMENT);
  857.                 ChangedComment();
  858.                 }
  859.             }
  860.         DisposHandle(typedText);
  861.         break;
  862.     case kCLIPMSG_CLEAR:
  863.         ResetMirAndComment();
  864.         length = 0L;
  865.         break;
  866.     }
  867. return(((length < 0) && (length != noTypeErr)) ? length : noErr);
  868. }
  869.  
  870. /* SelectLLine: selects a specified line in a list */
  871.  
  872. void SelectLLine(short whichList, short newSelect)
  873. {
  874. Point    cell;
  875.  
  876. cell.h = 0;
  877. cell.v = theSelection[whichList];
  878. LSetSelect(false, cell, Lists[whichList]);
  879. cell.v = newSelect;
  880. LSetSelect(true, cell, Lists[whichList]);
  881. LAutoScroll(Lists[whichList]);
  882. ChangedListSelection(cell, whichList, false);
  883. }
  884.  
  885. /* SetMir: calls UpdateMir and updates the document (Microprogram Editor) window */
  886.  
  887. void SetMir(unsigned long newmir)
  888. {
  889. union u_mir    oldmir;
  890.  
  891. oldmir = editmir;
  892. editmir.cstore = newmir;
  893. UpdateMir(editmir);
  894. /* …and update the control store memory */
  895. *(gCsMemory + theSelection[kL_COMMENTS]) = editmir;
  896. SetControlsFromMir(oldmir);
  897. }
  898.  
  899.  
  900. void DoClickSound(void)
  901. {
  902. SndCommand    mySndCmd;
  903. SndChannelPtr    mySndChan;
  904. register Handle    sndH;
  905.  
  906. mySndChan = nil;
  907. if (SndNewChannel(&mySndChan, 0, 0, gmyCallbackUPP) == noErr) {
  908.     if (sndH = Get1Resource('snd ', kSndPinzatrice)) {
  909.         if (gNumAsyncSnds == 0)
  910.             HLockHi(sndH);
  911.         mySndChan->userInfo = (long)sndH;
  912.         if (SndPlay(mySndChan, sndH, true) == noErr)
  913.             gNumAsyncSnds++;
  914.         mySndCmd.cmd = callBackCmd;
  915.         (void)SndDoCommand(mySndChan, &mySndCmd, true);
  916.         }
  917.     else
  918.         (void)SndDisposeChannel(mySndChan, false);
  919.     }
  920.  
  921. }
  922.  
  923.  
  924. /* procedure called when closing the MPrg window */
  925.  
  926. void CloseMicroProg(WindowPtr w)
  927. {
  928. DoCloseWindow(w, kMItem_Microprogram);
  929. }
  930.  
  931. void GotDragOnComments(void)
  932. {
  933. Rect    tempRect;
  934. Point    curMouse;
  935. register ListHandle    theList;
  936. register ListClickLoopUPP    savedLCkLoopUPP;
  937. register Boolean    wasLinked;
  938.  
  939. tempRect = *keyrects[kKEY_LIST];
  940. tempRect.right -= kScrollbarAdjust;
  941. SetCursor(*GetCursor(kSheetsCursor));
  942. GetMouse(&curMouse);
  943. theList = Lists[kL_COMMENTS];
  944. savedLCkLoopUPP = (*theList)->lClickLoop;
  945. (*theList)->lClickLoop = gSwitchCursClikLoopUPP;
  946.  
  947. (void)LClick(curMouse, gMyEvent.modifiers, theList);
  948. (*theList)->lClickLoop = savedLCkLoopUPP;
  949. GetMouse(&curMouse);
  950. wasLinked = PtInRect(curMouse, &tempRect);
  951. *(long *)&curMouse = 0L;
  952. if(LGetSelect(true, &curMouse, theList)) {
  953.     if (wasLinked) {
  954.         SetCursor(*GetCursor(kLinkedSheetsCursor));
  955.         DoClickSound();
  956.         DocumentIsDirty(true);
  957.         ChangedListSelection(curMouse, kL_COMMENTS, true);
  958.         }
  959.     else {
  960.         LSetSelect(false, curMouse, theList);
  961.         curMouse.h = 0;
  962.         curMouse.v = theSelection[kL_COMMENTS];
  963.         LSetSelect(true, curMouse, theList);
  964.         SysBeep(1);
  965.         }
  966.     }
  967. InitCursor();
  968. }
  969.  
  970. #endif
  971.  
  972.